/*
 * Hyplnk.h
 *
 *  Created on: Oct 13, 2018
 *      Author: ax
 */

#ifndef INCLUDE_HW_HYPLNK_H_
#define INCLUDE_HW_HYPLNK_H_

#include <Hwi.h>

typedef enum {
    Hyplnk_SOK = 0,
    Hyplnk_PWR_FAIL,    //failed when power on.
    Hyplnk_MAP_OV,
} Hyplnk_Status;

typedef enum {
    Hyplnk_MAP_CORE0_SL2 = 0,
    Hyplnk_MAP_CORE1_SL2,
    Hyplnk_MAP_CORE2_SL2,
    Hyplnk_MAP_CORE3_SL2,
    Hyplnk_MAP_CORE4_SL2,
    Hyplnk_MAP_CORE5_SL2,
    Hyplnk_MAP_CORE6_SL2,
    Hyplnk_MAP_CORE7_SL2,
    Hyplnk_MAP_MSMC_SRAM,
    //TODO add others here
    Hyplnk_MAP_BESIDE_DDR_MAX,
    Hyplnk_MAP_DDR3_SHM_START = 24, //start from 80000000 @ XXX
    //TODO add DDR3 map here
    Hyplnk_MAP_USED = 65,
    Hyplnk_MAP_MAX = 64,//entry in total
    Hyplnk_MAP_INVALID_
} Hyplnk_MapEntry;

#if ((Hyplnk_MAP_USED > Hyplnk_MAP_MAX) || (Hyplnk_MAP_BESIDE_DDR_MAX > Hyplnk_MAP_DDR3_SHM))
#error Hyper link map overflowed, adjust you Hyplnk_MapEntry & Hyplnk_MapEntity.
#endif

#define Hyplnk_BASE         0x40000000
#define Hyplnk_WINDOW(IDX)  (Hyplnk_BASE + 0x00400000 * (IDX))
#define Hyplnk_WINDOW(IDX)  (Hyplnk_BASE + 0x00400000 * (IDX))


#define VUSR_BASE(BASE)     (BASE >> 16)
#define VUSR_SEGSZ(POW)     (POW - 1)

typedef struct {
    Uint32 base   : 16;
    Uint32 indx   :  6;
    Uint32 sz     :  5;
    Uint32 rsvd   :  4;
    Uint32 valid  :  1;
} Hyplnk_MapEntity;

#ifdef __Hyplnk_INIT_HERE__
static const Hyplnk_MapEntity Hyplnk_MapTable[Hyplnk_MAP_MAX] = {
    {.base = VUSR_BASE(0x10800000), .indx =  0, .sz = VUSR_SEGSZ(19), .valid = VALID},
    {.base = VUSR_BASE(0x11800000), .indx =  1, .sz = VUSR_SEGSZ(19), .valid = VALID},
    {.base = VUSR_BASE(0x12800000), .indx =  2, .sz = VUSR_SEGSZ(19), .valid = VALID},
    {.base = VUSR_BASE(0x13800000), .indx =  3, .sz = VUSR_SEGSZ(19), .valid = VALID},
    {.base = VUSR_BASE(0x14800000), .indx =  4, .sz = VUSR_SEGSZ(19), .valid = VALID},
    {.base = VUSR_BASE(0x15800000), .indx =  5, .sz = VUSR_SEGSZ(19), .valid = VALID},
    {.base = VUSR_BASE(0x16800000), .indx =  6, .sz = VUSR_SEGSZ(19), .valid = VALID},
    {.base = VUSR_BASE(0x17800000), .indx =  7, .sz = VUSR_SEGSZ(19), .valid = VALID}, /*core[0:7]'s L2 RAM from 0~7*/
    {.base = VUSR_BASE(0x0C000000), .indx =  8, .sz = VUSR_SEGSZ(22), .valid = VALID}, /*MSMC RAM*/
    {.base = VUSR_BASE(0x02A00000), .indx =  9, .sz = VUSR_SEGSZ(21), .valid = VALID}, /*QM configuration*/
    {.base = VUSR_BASE(0x34000000), .indx = 10, .sz = VUSR_SEGSZ(21), .valid = VALID}, /*QM data*/
    {.base = VUSR_BASE(0x10800000), .indx = 11, .sz = VUSR_SEGSZ(19), .valid = VALID},
    {.indx = 12}, {.indx = 13}, {.indx = 14}, {.indx = 15}, {.indx = 16}, {.indx = 17},
    {.indx = 18}, {.indx = 19}, {.indx = 20}, {.indx = 21}, {.indx = 22}, {.indx = 23},/*prepare for other peripherals */
    {.base = 0x80000000 >> 16, .indx = 24, .sz = VUSR_SEGSZ(22), .valid = VALID},/*DDR*/
    /*add below*/ {}
};
#else
extern Hyplnk_MapEntity Hyplnk_MapTable[];
#endif//EOF __Hyplnk_INIT_HERE__


extern
Hyplnk_Status __init
Hyplnk_setup(
    Hyplnk_MapEntity* hmtlb,    //use Hyplnk_MapTable by default
    Uint16            event,
    Loopback          loopback
);

typedef enum {
    Hyplnk_Test = 0,
    Hyplnk_add_your_code_O_cmd_here_And_DONOT_LG_Hyplnk_CMD_MAX,//TODO
    Hyplnk_CMD_MAX = 30,
    Hyplnk_ErrorStatusCmd,
    Hyplnk_CMD_INVALID
} Hyplnk_Cmd;


extern Hyplnk_Cmd Hyplnk_PeerCmd;

extern
void
Hyplnk_post(
    Hyplnk_Cmd code
);

void __init
Hyplnk_isrHookAdd(
    void* isre,
    void* arg
);

#endif /* INCLUDE_HW_HYPLNK_H_ */
